package com.zyl.edthresholdtraining.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zyl.edthresholdtraining.common.AppConstant;
import com.zyl.edthresholdtraining.dto.UserTestDTO;
import com.zyl.edthresholdtraining.entity.*;
import com.zyl.edthresholdtraining.enums.ChooseTypeEnum;
import com.zyl.edthresholdtraining.enums.TestTypeEnum;
import com.zyl.edthresholdtraining.mapper.UserResponseMapper;
import com.zyl.edthresholdtraining.vo.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author jiangtingfeng
 * @description
 * @date 2020/7/31/031
 */
@Slf4j
@Service
public class UserResponseService extends ServiceImpl<UserResponseMapper, UserResponse> {

    @Autowired
    private UserTestAnswerService userTestAnswerService;

    @Autowired
    private UserTestTimeService userTestTimeService;

    @Autowired
    private UserTestResultService userTestResultService;

    @Autowired
    private TimeConfigureService timeConfigureService;
    /**被试测试次数限定*/
    private Integer testTimes;
    /**被试测试时间区间*/
    private String timePartition;
    /**被试测试时每个时间分区可以进行测试的时间(单位ms)*/
    private Long testTime;
    /**当前时间分区*/
    private String currentPartition;
    /** 图片切换时间*/
    private Integer changeImageTime;

    @Autowired
    private TimePartitionAllowService timePartitionAllowService;


    public boolean check(UserTestDTO userTestDTO, HttpServletRequest request) {
        Long id = (Long)request.getSession().getAttribute(AppConstant.USER_ID);
        UserTestAnswer userTestAnswer = get(id, userTestDTO.getImageUnitName());
        if (userTestAnswer.getNumberResult().intValue() == userTestDTO.getUserResponse()) {
            return true;
        } else {
            return false;
        }
    }

    public UserTestAnswer get(Long id,String imageUnitName){
        QueryWrapper<UserTestAnswer> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",id)
                .eq("image_unit_name",imageUnitName);
        List<UserTestAnswer> userTestAnswerList = userTestAnswerService.list(queryWrapper);
        if (CollectionUtils.isEmpty(userTestAnswerList)) {
            throw new BaseException("找不到该被试对应测试的答案！");
        }
        UserTestAnswer userTestAnswer = userTestAnswerList.get(0);
        return userTestAnswer;
    }

    private void init() {
        List<TimeConfigure> list = timeConfigureService.list();
        if (CollectionUtils.isEmpty(list)) {
            throw new BaseException("时间配置信息出错！");
        }
        TimeConfigure timeConfigure = list.get(0);
        testTimes = timeConfigure.getUserTestTimes();
        timePartition = timeConfigure.getTimePartition();
        testTime = timeConfigure.getTestTime() * 60 * 1000L;
        changeImageTime = timeConfigure.getChangeImageTime() == null ? 500 : timeConfigure.getChangeImageTime();
    }

    @Transactional(rollbackFor = Exception.class)
    public UserTestResult saveResult(HttpServletRequest req, String[] timeList, String[] answerList,Integer type,Long userId) {
        //Long userId = (Long) req.getSession().getAttribute(AppConstant.USER_ID);
        String uuid = (String)req.getSession().getAttribute(AppConstant.USER_ID+type+""+userId);
        //保存被试第几次测试
        Integer userTestTimes = getUserTestTime(type,req,userId);
        List<UserTestTime> userTestTimeList = new ArrayList<>();
        List<UserResponse> userResponseList = new ArrayList<>();
        int index = 0;
        double sum = 0.0;
        double sumRight = 0.0;
        for (int i = 0; i < answerList.length; i++) {
            /**
             * 拼装用户测试时间数据
             * */
            String[] answer= answerList[i].split(",");
            UserTestTime userTestTime = new UserTestTime();
            userTestTime.setUserId(userId);
            userTestTime.setType(type);
            userTestTime.setImageUnitName(answer[0]);
            userTestTime.setTestTime(timeList[i]);
            sum = sum + Integer.parseInt(timeList[i]);
            userTestTimeList.add(userTestTime);

            /**
             * 拼装用户测试回答的结果数据
             * 并将用户回答的结果和正确答案进行匹配
             * 将结果写入到userTestResult
             * */
            UserResponse userResponse = new UserResponse();
            userResponse.setUserId(userId);
            userResponse.setType(type);
            userResponse.setImageUnitName(answer[0]);
            userResponse.setUserTestResponse(Integer.parseInt(answer[1]));
            userResponse.setAnswerWord(answer[2]);
            UserTestAnswer userTestAnswer = get(userId, answer[0]);
            if (userTestAnswer == null) {
                return null;
            }
            if (userTestAnswer.getNumberResult().intValue() == Integer.parseInt(answer[1])) {
                userResponse.setResult(ChooseTypeEnum.CHOOSE_ONE.getValue());
                if (Integer.parseInt(answer[1]) != -16) {
                    index++;
                    sumRight = sumRight + Integer.parseInt(timeList[i]);
                }
            } else {
                userResponse.setResult(ChooseTypeEnum.CHOOSE_ZONE.getValue());
            }
            userResponse.setGroupNumber(userTestTimes);
            userResponseList.add(userResponse);
        }
        //保存被试每个block的正确率
        UserTestResult userTestResult = new UserTestResult();
        userTestResult.setUserId(userId);
        userTestResult.setGroupNumber(userTestTimes);
        userTestResult.setType(type);
        //算正确率
        double rate = index / Double.valueOf(AppConstant.GROUP_NUMBER);
        BigDecimal bg = new BigDecimal(rate*100);
        BigDecimal bigDecimal = bg.setScale(4, BigDecimal.ROUND_HALF_UP);
        userTestResult.setRightRate(bigDecimal);
        //算平均反应时  只算正确的回答反应时
        double avgTime = 0.0;
        if (index != 0) {
            avgTime = sumRight / Double.valueOf(index);
        }
        userTestResult.setAvgTime(avgTime);
        userTestResult.setTimePartitionUuid(uuid);
        userTestResultService.save(userTestResult);
        userTestTimeService.saveBatch(userTestTimeList);
        userResponseList.forEach(userResponse ->baseMapper.insert(userResponse));

        //如果是训练的或将测试次数改成和时间记录表进行修改获取配置表信息
        return userTestResult;
    }
    /**
     *  if (type == TestTypeEnum.TEST_ONE.getValue().intValue()) {
     *             init();
     *             req.getSession().setAttribute(AppConstant.MAX_TRAIN_TIMES + userId,testTimes);
     *             //修改记录表
     *             TimePartitionAllow timePartitionAllow = new TimePartitionAllow();
     *             QueryWrapper<TimePartitionAllow> queryWrapper = new QueryWrapper<>();
     *             queryWrapper.eq("user_id",userId).eq("time_partition",AppConstant.TIME_PARTITION_TRAIN);
     *             List<TimePartitionAllow> timePartitionAllowList = timePartitionAllowService.list(queryWrapper);
     *             if (CollectionUtils.isEmpty(timePartitionAllowList)) {
     *                 log.info("获取时间控制表信息失败");
     *                 throw new BaseException("获取时间控制表信息失败");
     *             }
     *             timePartitionAllow = timePartitionAllowList.get(0);
     *             timePartitionAllow.setStartTime(System.currentTimeMillis());
     *             timePartitionAllowService.updateById(timePartitionAllow);
     *         }
     * */

    private Integer getUserTestTime(Integer type,HttpServletRequest req,Long userId) {
        Integer userTestTimes = 0;
        HttpSession session = req.getSession();
        if (TestTypeEnum.TEST_ONE.getValue().intValue() == type) {
            userTestTimes = getUserTestTime(userId,session,AppConstant.USER_TRAIN_TIMES,AppConstant.USER_TRAIN_TIMES_VALUE,type);
        } else {
            userTestTimes = getUserTestTime(userId,session,AppConstant.USER_TEST_TIMES,AppConstant.USER_TEST_TIMES_VALUE,type);
        }
        return userTestTimes;
    }

    private Integer getUserTestTime(Long userId,HttpSession session, String userTrainTimes, Integer userTrainTimesValue,Integer type) {
        Integer userTestTimes = 0;
        userTestTimes = (Integer)session.getAttribute(userTrainTimes);
        if (userTestTimes == null) {
            //判断被试是否已经进行测试
            QueryWrapper<UserResponse> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id",userId).eq("type",type).orderByDesc("group_number");
            List<UserResponse> userResponseList = baseMapper.selectList(queryWrapper);
            if (CollectionUtils.isEmpty(userResponseList)) {
                userTestTimes = userTrainTimesValue;
            }else {
                userTestTimes = userResponseList.get(0).getGroupNumber() + 1;
            }
            session.setAttribute(userTrainTimes,userTestTimes);
        } else {
            userTestTimes = userTestTimes + 1;
            session.setAttribute(userTrainTimes,userTestTimes);
        }
        return userTestTimes;
    }
    /*public static void main(String[] args) {
        for (int j = 0; j < 10; j++) {

            for (int i = 0; i < 10; i++) {
                double a = i/Double.valueOf(AppConstant.GROUP_NUMBER);
                BigDecimal bg = new BigDecimal(a*100);
                BigDecimal bigDecimal = bg.setScale(4, BigDecimal.ROUND_HALF_UP);
                System.out.println(bigDecimal);
            }
        }

    }*/
}


